# -*- coding: utf-8 -*-

"""
@Remark: 自定义异常处理
"""
import logging
import re
import traceback
from django.db.utils import DataError
from django.db.models import ProtectedError
from django.http import Http404
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed
from rest_framework.views import set_rollback

from common.response import JsonResponse

logger = logging.getLogger("django")


def exception_handler(ex, context):
    """
    统一异常拦截处理
    目的:(1)取消所有的500异常响应,统一响应为标准错误返回
        (2)准确显示错误信息
    :param ex:
    :param context:
    :return:
    """
    msg = ''
    code = 400

    if isinstance(ex, AuthenticationFailed):
        code = 401
        msg = ex.detail
    elif isinstance(ex, DRFAPIException):
        set_rollback()
        msg = ex.detail
    elif isinstance(ex, DataError):
        if len(ex.args) == 2:
            error_msg = ex.args[1]
            matched = re.fullmatch(r"^Out of range value for column '(\w+)' at row \d+$", error_msg)
            if matched:
                field = matched.groups()[0]
                msg = f"字段【{field}】超过最大数量限制！"
                return JsonResponse(success=False, msg=msg, code=code)

        msg = str(ex)
        logger.error(traceback.format_exc())

    elif isinstance(ex, ProtectedError):
        set_rollback()
        msg = "删除失败:该条数据与其他数据有相关绑定"
    elif isinstance(ex, Http404):
        msg = "对象不存在或已删除！"
        code = 404

    elif isinstance(ex, Exception):
        logger.error(traceback.format_exc())
        msg = str(ex)

    return JsonResponse(success=False, msg=msg, code=code)
